Sandbox/Old Memory
= Memory = Java makes a number of assumptions about the memory usage patterns of programs. While generally appropriate for web servers, and programs that generate web pages from databases, these assumptions are generally very poor for Minecraft. The following is a "current best practice" idea for starting Minecraft with better memory settings. These are NOT specific to Mystcraft. %%**%% WARNING! \\ Portions of these recommendations are java-6 specific. This was not understood at the time this was developed. Eyamaz has been doing similar studies with Java 7 and a variety of modpacks; please consult http://forum.feed-the-beast.com/threads/jvm-arguments-for-modded-minecraft-updated-12-30-13.28994/ for more information over there. **The following is seriously overdue for a re-examination.** %%**%% DANGER! Danger Will Robinson! Something seems to have changed very recently. Mac java 6 update 45 is not behaving the same as prior ones. Investigation is ongoing. %%**%% Found: "MaxNewSize" now prohibits space from being used by tenured, yet does not actually let space be used by "new" either. Testing to see if Oracle's java behaves like mac java ... Clients For clients: Initial client recommendation -- place this into your launcher's "Advanced java flags" (it will have different names in different launchers): ( Removed: -XX:MaxNewSize=500m -- see above, testing in progress ) -XX:NewSize=84m -d32 -server -XX:+UseAdaptiveGCBoundary -XX:SurvivorRatio=1 -XX:TargetSurvivorRatio=90 -XX:CompileThreshold=300 -XX:CMSInitiatingOccupancyFraction=80 -XX:SoftRefLRUPolicyMSPerMB=0 -XX:MaxPermSize=150m -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:MaxHeapFreeRatio=25 -XX:MinHeapFreeRatio=21 -XX:+DisableExplicitGC -XX:MaxTenuringThreshold=4 -XX:+PrintHeapAtGC -XX:+PrintTenuringDistribution -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -Xloggc:GC.log Servers The following is the recommended starting point for a mystcraft server. This should go into whatever batch/script file you use to start it up. NB: A much better script (with adjustable constants) for linux/unix systems can be found at that linked forum thread! This is for servers, not clients/single player: ( Removed: -XX:MaxNewSize=450m -- see above, testing in progress ) java \ -d32 -server \ -Xms200m -Xmx500m \ -XX:+UseAdaptiveGCBoundary \ -XX:TargetSurvivorRatio=90 \ -XX:NewSize=114m \ -XX:SurvivorRatio=1 \ -XX:CompileThreshold=300 \ -XX:+UseConcMarkSweepGC -XX:+UseParNewGC \ -XX:CMSInitiatingOccupancyFraction=80 \ \ -XX:SoftRefLRUPolicyMSPerMB=0 \ -XX:MaxPermSize=150m \ -XX:+UseParNewGC \ -XX:MaxHeapFreeRatio=25 \ -XX:MinHeapFreeRatio=21 \ -XX:+DisableExplicitGC \ -XX:MaxTenuringThreshold=4 \ -XX:+PrintHeapAtGC -XX:+PrintTenuringDistribution \ -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -Xloggc:GC.log \ -jar new_server.jar nogui The key points of this command: -d32 -server \ This is for up to 2.5 GB of heap (the "-Xmx" value). If you use more than this, use "-d64 -XX:+UseCompressedOops -server". -XX:NewSize=114m -XX:MaxNewSize=450m \ -XX:SurvivorRatio=1 \ This sets up memory allocation. This works for small servers (1-3 players); it will probably not work for larger (20 person) servers. It starts with "new" memory broken into (114 / (1+2)) = 38 MB sections. This is used for temporary space as people move around. Rapid use of multiple link/D-books by multiple people to multiple new areas will overflow this. A single party staying mostly together will not. It is possible that a mapper add-on may load chunks rapidly enough to overflow this also. -XX:+UseConcMarkSweepGC -XX:+UseParNewGC \ -XX:CMSInitiatingOccupancyFraction=80 \ The default garbage collector is designed to collect "tenured" space as fast as possible, but stops the program to do so. For real-time response, that's bad. CMS is a collector designed to not stop the program as it collects tenured. For Minecraft, this is good. The critical issue here: Collecting tenured gets more expensive as tenured gets bigger. This means that tossing more memory at minecraft can slow it down with the default collector. CMS avoids that issue. -XX:+PrintHeapAtGC -XX:+PrintTenuringDistribution \ -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -Xloggc:GC.log \ This logs the garbage collection results to a file, so you can inspect them. If you run into problems, please post at that linked forum thread (use Pastebin or something similar for your GC log file). Theory and background Please note that Mystcraft does not stress memory access in Java that badly in single player. Other mods can be much worse; the settings here should be sufficient for most, but are not sufficient for all. In general, linkbook travel is around the same impact as nether portal travel; in multiplayer, because linkbooks can allow players to split up rapidly, the total memory usage can go up faster. This primarily means that the rate of generation of garbage goes up. Additionally, as players spread out, more chunks are loaded; this drives up the usage of "tenured" space. For additional information, please see this thread on the Minecraft forums: http://www.minecraftforum.net/topic/1541173-java-memory-and-minecraft/ If you know about "Garbage first" garbage collection, please note that: - No testing has been done with that collector; it may (probably will) work better than this, and - I am looking for more information on that collector (have found some documentation, but only one report from people who have gone before me on using it with Minecraft). Reading the garbage collection logs A typical segment out output looks like: {Heap before GC invocations=18 (full 8): par new generation total 89600K, used 79033K 000000000f400000, 000000000f400000) eden space 76800K, 100% used [0000000009000000, 000000000db00000, 000000000db00000) from space 12800K, 17% used [000000000db00000, 000000000dd2e5f0, 000000000e780000) to space 12800K, 0% used [000000000e780000, 000000000e780000, 000000000f400000) concurrent mark-sweep generation total 90584K, used 42055K [000000000f400000, 0000000014c76000, 0000000028400000) concurrent-mark-sweep perm gen total 19584K, used 17177K [0000000028400000, 0000000029720000, 000000002c400000) 130.355: [GC 130.355: [ParNew Desired survivor size 6553600 bytes, new threshold 4 (max 4) - age 1: 47464 bytes, 47464 total - age 2: 35720 bytes, 83184 total - age 3: 1569856 bytes, 1653040 total - age 4: 44184 bytes, 1697224 total : 79033K->2644K(89600K), 0.0049987 secs 121089K->44756K(180184K), 0.0050522 secs] user=0.01 sys=0.00, real=0.01 secs Heap after GC invocations=19 (full 8): par new generation total 89600K, used 2644K [0000000009000000, 000000000f400000, 000000000f400000) eden space 76800K, 0% used [0000000009000000, 0000000009000000, 000000000db00000) from space 12800K, 20% used [000000000e780000, 000000000ea153f8, 000000000f400000) to space 12800K, 0% used [000000000db00000, 000000000db00000, 000000000e780000) concurrent mark-sweep generation total 90584K, used 42111K [000000000f400000, 0000000014c76000, 0000000028400000) concurrent-mark-sweep perm gen total 19584K, used 17177K [0000000028400000, 0000000029720000, 000000002c400000) } The key lines here: concurrent mark-sweep generation total 90584K, used 42111K [000000000f400000, 0000000014c76000, 0000000028400000) This shows the long-term allocation and usage. Desired survivor size 6553600 bytes, new threshold 4 (max 4) As long as the threshold stays 4, the rate of garbage generation is not overwhelming Java ("new" and "survivor" are large enough). - age 4: 44184 bytes, 1697224 total This shows the memory used in the "new" space. Compare this to the target survivor size.